package threading;


//基于数组来实现队列
class MyBlockingQueue{
    private int[] items = new int[1000];
    //约定队列的有效元素[head,tail)前闭后开
    volatile private int head = 0;
    volatile private int tail = 0;
    volatile private int size = 0;

    //入队列
    synchronized public void put(int elem) throws InterruptedException {
        while(size == items.length){
            //队列满了，插入失败
            //return ;
            this.wait();
        }
        //把新元素放到tail所在位置上
        items[tail] = elem;
        tail++;
        //如果tail走到了数组的末尾，就需要让tail从头再来。
        if(tail == items.length){
            tail = 0;
        }
        //tail = tail % items.length;//这个写法也可以让队列达成循环队列的效果
        size++;
        this.notify();
    }
    //出队列
    synchronized public Integer take() throws InterruptedException {
        while(size == 0){
            //return null;
            this.wait();
        }
        int value = items[head];
        head++;
        size--;
        if(head == items.length){
            head = 0;
        }
        this.notify();
        return value;
    }
}

public class ThreadDemo21 {
    public static void main1(String[] args) {
        MyBlockingQueue myBlockingQueue = new MyBlockingQueue();
        //消费者
        Thread t1 = new Thread(()->{
            while(true){
                try {
                  int value = myBlockingQueue.take();
                    System.out.println("消费者："+value);
                    Thread.sleep(1000);//可以让消费者等1s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();

        //生产者
        Thread t2 = new Thread(()->{
            int value = 0;
            while(true){
                try {
                    System.out.println("生产者："+value);
                    myBlockingQueue.put(value);
                    value++;
                    //Thread.sleep(1000);//也可以让生产者等1s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t2.start();
    }
}
